<template>
  <h2>计算属性和监视</h2>
  <fieldset>
    <legend>姓名操作</legend>

    <input type="text" v-model="date" />
    <!-- v-modle 用来绑定表单元素的值 -->
    姓氏:<input type="text" v-model="user.firstName" /> <br />
    名字:<input type="text" v-model="user.lastName" /> <br />
  </fieldset>
  <hr />
  <fieldset>
    <legend>计算属性和监视的演示</legend>

    姓名:<input type="text" v-model="fullname" /> <br />
    姓名:<input type="text" v-model="fullname2" /> <br />
    姓名:<input type="text" v-model="fullName3" />
  </fieldset>

  <h1 v-bind[onename]="any">{{ onename }}</h1>

  <h1>{{ anmi }}hahah</h1>

  <h2>{{ anmis() }}</h2>

  <h2>{{ a }}</h2>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  onMounted,
  reactive,
  ref,
  watch,
  onBeforeMount,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted
} from "vue";

export default defineComponent({
  // 注意想要实现响应式的数据必须要加上 ref或者是 reactive

  // data  [method,computed,watch] => method 执行方法是直接执行的,而computed如果数据没有发生改变,那么刷新页面也不会发生改变(计算属性是基于它们的反应依赖关系缓存的)
  //  watch 监视程序一开始执行的时候不会触发watch,只有等值发生改变时才会触发,一般用于较复杂的计算(当需要在数据变化时执行异步或开销较大的操作时，这个方式是最有用的)

  // toRefs(可以把响应式对象转换成普通对象,该普通对象的每一个属性都是 ref)

  // ref 还有一个作用,当页面加载完毕,只需要给标签加一个 ref = "名字"  可以直接通过名字去操作该dom元素

  // shallowref(如果是对象内部就没有做代理处理了) 和 shallowReactive  浅响应式

  // readonly shallowreadonly  深度只读和浅只读

  // toRwa(把代理对象变成普通对象) 和 markRaw(使其永远不会转换为代理。返回对象本身。)

  //toRef 可以把对象里的属性变成ref对象

  // customRef 自定义ref track() 和tirgger()

  // private  和 inject 用来跨组件传递数据

  // 判断是否是响应式 isRef isReactive isReadonly isProxy

  //Vue 不能检测以下数组的变动：

  // 当你利用索引直接设置一个数组项时，例如：vm.items[indexOfItem] = newValue
  // 当你修改数组的长度时，例如：vm.items.length = newLength

  name: "App",
  setup() {
    const user = reactive({
      firstName: "萨勒",
      lastName: "芬妮"
    });
    const da = ref(Date.now());
    // 使用计算属性的方式显示 姓名在第一个输入框 ,传入一个回调标识get操作 ,如果想要set操作必须传入一个对象,里面实现get和set
    const fullname = computed(() => {
      return user.firstName + "_" + user.lastName;
    });

    const fullname2 = computed({
      get() {
        return user.firstName + "_" + user.lastName;
      },
      set(val: string) {
        const names = val.split("_");
        user.firstName = names[0];
        user.lastName = names[1];
      }
    });

    const fullName3 = ref("");
    // 监视 ,在一开始没有执行
    watch(
      user,
      ({ firstName, lastName }) => {
        fullName3.value = firstName + lastName;
      },
      { immediate: true, deep: true } //immediate 一开就执行,deep深度监视
    );
    // watchEffect(()=>{})

    const date = computed({
      get() {
        return da.value + user.firstName;
      },
      set(val: string) {
        console.log(val, "cc");
      }
    });

    onBeforeMount(() => {
      console.log("--onBeforeMount");
    });

    onMounted(() => {
      console.log("--onMounted");
    });

    onBeforeUpdate(() => {
      console.log("--onBeforeUpdate");
    });

    onUpdated(() => {
      console.log("--onUpdated");
    });

    onBeforeUnmount(() => {
      console.log("--onBeforeUnmount");
    });

    onUnmounted(() => {
      console.log("--onUnmounted");
    });
    return {
      user,
      fullname,
      fullname2,
      fullName3,
      date,
      onename: "sss"
    };
  },

  data() {
    console.log(this, "cc");
    const user1 = ref("mamama");
    return {
      user1,
      a: 1
    };
  },

  computed: {
    anmi(): any {
      console.log(this);
      console.log(defineComponent);
      const cm = this.user.firstName;
      return cm;
    }
  },

  methods: {
    anmis() {
      return "7777";
    }
  },
  watch: {}

  // updated(){

  //     this.da = Date.now()
  // }

  // vue2中的
  // computed: {
  //   fullName3: {
  //     get(): string {
  //       return this.user.firstName + "_" + this.user.lastName;
  //     },
  //     set(val) {
  //       const names = val.split("_");
  //       this.user.firstName = names[0];
  //       this.user.lastName = names[1];
  //     },
  //   },
  // },
});
</script>

<style scoped></style>
